package com.smartstate.EnvironmentMonitor.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartstate.EnvironmentMonitor.dto.DataDTO;
import com.smartstate.EnvironmentMonitor.dto.PageDTO;
import com.smartstate.EnvironmentMonitor.dto.ReportDTO;
import com.smartstate.EnvironmentMonitor.entity.Report;
import com.smartstate.EnvironmentMonitor.mapper.DataMapper;
import com.smartstate.EnvironmentMonitor.mapper.HistoryMapper;
import com.smartstate.EnvironmentMonitor.service.HistoryService;
import com.smartstate.EnvironmentMonitor.vo.DataVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class HistoryServiceImpl extends ServiceImpl<HistoryMapper, Report> implements HistoryService {

    @Autowired
    private HistoryMapper historyMapper;

    @Override
    public Page<Report> queryAllPageByDTO(PageDTO pageDTO) {
        return null;
    }

    @Resource
    private DataMapper dataMapper;

    /**
     * 根据设备id，读取历史曲线数据
     * @param dataDTO
     * @return
     */
    @Override
    public Map<String, List<DataVO>> getHistoryCurve(DataDTO dataDTO) {
        return check(dataDTO);
    }

    /**
     * 用于实时数据查询前59秒的
     * @param id
     * @return
     */
    @Override
    public List<Report> getHistoryCurveByDeviceId(String id) {
        DateTime dateTime = new DateTime();
        String nowDate = dateTime.toString();
        DateTime startDate = dateTime.offsetNew(DateField.MINUTE, -3 );
        return historyMapper.getHistoryCurveByDeviceId(id, startDate.toString(), nowDate);
    }

    /**
     * 自定义查询
     * @return
     */
    @Override
    public Map<String, List<DataVO>> getHistoryCurveByDataDTO(DataDTO dataDTO) {
        return check(dataDTO);
    }

    /**
     * 查询数据的逻辑处理
     * @param dataDTO
     * @return
     */
    public Map<String, List<DataVO>> check(DataDTO dataDTO){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, List<DataVO>> mapList = new HashMap<>();
//        遍历获取每个设备id对于的属性集合，筛选出用户指定查询的属性
        Map<String, List<String>> map = dataDTO.getMap();
        DateTime dateTime = new DateTime();
        String nowDate = dateTime.toString();
        for (String deviceId : map.keySet()) {
//            判断deviceId对应的表是否存在
            String objId = dataMapper.queryIdByDeviceId(deviceId);
            String tableIsEmpty = historyMapper.queryTableIsEmpty(objId);
            if (tableIsEmpty != null){
                ReportDTO dto = (ReportDTO) dataDTO.getDto();
                dto = getTimeUnit(dto);
                List<Report> list = historyMapper.queryHistoryData(objId, dto, nowDate);
                for (String attribute : map.get(deviceId)) {
                    List<DataVO> arrayList = new ArrayList<>();
                    list.forEach((item) -> {
                        Object currentValue = invokeGet(item, attribute);
                        if (currentValue != null) {
                            DataVO dataVO = new DataVO();
                            dataVO.setCurrentValue(currentValue.toString());
                            dataVO.setAttribute(attribute);
                            dataVO.setTime(simpleDateFormat.format(item.getDateTime()));
                            dataVO.setId(deviceId);
                            arrayList.add(dataVO);
                        }
                    });
                    mapList.put(deviceId + "." + attribute,arrayList);
                }
            }
        }
        return mapList;
    }

    /**
     * java反射bean的get方法
     *
     * @param
     * @param fieldName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Method getGetMethod(Report objectClass, String fieldName) {
        StringBuffer sb = new StringBuffer();
        sb.append("get");
        sb.append(fieldName.substring(0, 1).toUpperCase());
        sb.append(fieldName.substring(1));
        try {
            return objectClass.getClass().getMethod(sb.toString());
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 执行get方法
     *
     * @param o 执行对象
     * @param fieldName 属性
     */
    public static Object invokeGet(Report o, String fieldName) {
        Method method = getGetMethod(o, fieldName);
        if (method == null){
            return null;
        }
        try {
            return method.invoke(o, new Object[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 时间换算
     * @param reportDTO
     * @return
     */
    public ReportDTO getTimeUnit(ReportDTO reportDTO){
        String timeNumber = reportDTO.getTimeNumber();
        switch (timeNumber){
            case "1" :
                reportDTO.setTimeUnit("s");
                break;
            case "60":
                reportDTO.setTimeUnit("m");
                break;
            case "3600":
                reportDTO.setTimeUnit("h");
                break;
            default:
                reportDTO.setTimeUnit("d");
        }
        reportDTO.setTimeNumber("1");
        return reportDTO;
    }
}
